from fastapi import Query
from fastapi import FastAPI
app = FastAPI()

# 花花直播助手弹幕API转发接口（调用 tools.huahua_danmu_api 实现）
from tools.huahua_danmu_api import send_huahua_danmu
@app.post("/api/huahua/send_danmu")
async def api_huahua_send_danmu(text: str = Query(..., description="要发送的弹幕内容")):
    """
    调用花花直播助手弹幕API发送弹幕
    """
    return await send_huahua_danmu(text)
# 主程序进程管理
import subprocess
import threading
import time
main_process = None
main_output = ''
main_status = '已停止'
main_lock = threading.Lock()



def read_process_output(stream):
    global main_output
    while True:
        line = stream.readline()
        if not line:
            break
        main_output += line
        if len(main_output) > 8000:
            main_output = main_output[-8000:]

def start_main_process():
    global main_process, main_status, main_output
    with main_lock:
        if main_process and main_process.poll() is None:
            return False, '主程序已在运行'
        main_output = ''
        main_status = '启动中'
        main_process = subprocess.Popen([
            sys.executable, 'main.py'
        ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
        threading.Thread(target=read_process_output, args=(main_process.stdout,), daemon=True).start()
        threading.Thread(target=read_process_output, args=(main_process.stderr,), daemon=True).start()
        main_status = '运行中'
        return True, '主程序已启动'

def stop_main_process():
    global main_process, main_status
    with main_lock:
        if main_process and main_process.poll() is None:
            main_process.terminate()
            try:
                main_process.wait(timeout=5)
            except Exception:
                main_process.kill()
            main_status = '已停止'
            return True, '主程序已停止'
        else:
            main_status = '已停止'
            return False, '主程序未在运行'

def restart_main_process():
    stop_main_process()
    time.sleep(1)
    return start_main_process()

def get_main_status():
    global main_process, main_status, main_output
    if main_process and main_process.poll() is None:
        main_status = '运行中'
    else:
        main_status = '已停止'
    return {
        'status': main_status,
        'output': main_output[-8000:]
    }


# 集成 blivedm 弹幕缓存API
import sys
sys.path.append('.')

from fastapi import FastAPI, Request
from contextlib import asynccontextmanager
from fastapi.responses import FileResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from tools.config_api import get_config, save_config
import asyncio
from core.ai.engine import AIEngine
from utils.config_loader import get_config as get_global_config


# 全局弹幕缓存（线程安全，最多100条）
from collections import deque
danmu_cache = deque(maxlen=100)
import threading
danmu_cache_lock = threading.Lock()



app = FastAPI()

# 弹幕面板API，返回最近弹幕
@app.get("/api/danmu/recent")
def api_danmu_recent():
    with danmu_cache_lock:
        return {"danmus": list(danmu_cache)}

# 新增：POST接口，供主程序推送弹幕
from fastapi import Request
@app.post("/api/danmu/add")
async def api_danmu_add(request: Request):
    data = await request.json()
    uname = data.get("uname")
    msg = data.get("msg")
    if not uname or not msg:
        return {"success": False, "msg": "缺少uname或msg"}
    add_danmu_to_cache(uname, msg)
    return {"success": True}

# AI 聊天接口
from fastapi import Body
from fastapi.responses import JSONResponse
@app.post("/api/ai/chat")
async def api_ai_chat(data: dict = Body(...)):
    """
    请求体: { "prompt": "用户输入" }
    返回: { "success": true, "reply": "AI回复" }
    """
    prompt = data.get("prompt", "")
    if not prompt:
        return JSONResponse({"success": False, "msg": "缺少prompt参数"})
    try:
        config = get_global_config()
        ai_engine = AIEngine(config)
        reply = await ai_engine.get_ai_response(prompt)
        return {"success": True, "reply": reply}
    except Exception as e:
        return JSONResponse({"success": False, "msg": str(e)})

def add_danmu_to_cache(uname, msg):
    with danmu_cache_lock:
        danmu_cache.append({"uname": uname, "msg": msg})

# 主程序控制API
@app.get('/api/status')
def api_status():
    return get_main_status()

@app.post('/api/start')
def api_start():
    ok, msg = start_main_process()
    return {'success': ok, 'msg': msg}

@app.post('/api/stop')
def api_stop():
    ok, msg = stop_main_process()
    return {'success': ok, 'msg': msg}

@app.post('/api/restart')
def api_restart():
    ok, msg = restart_main_process()
    return {'success': ok, 'msg': msg}
from tools.bili_api import get_qrcode, get_qrcode_status
import os




# 兼容 PyInstaller 打包和源码运行，始终指向 exe/py 同级 webui/dist
# 兼容源码和打包运行，始终指向 fastapi_server.py/exe 所在目录的 webui/dist
import os, sys
if getattr(sys, 'frozen', False):
    # PyInstaller 打包后
    base_dir = os.path.dirname(sys.executable)
else:
    # 源码运行，始终以项目根目录为基准（即本文件的上级目录）
    base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
static_dir = os.path.join(base_dir, 'webui', 'dist')

# 挂载 /assets 路由，解决前端静态资源 404
assets_dir = os.path.join(static_dir, 'assets')
if os.path.isdir(assets_dir):
    app.mount("/assets", StaticFiles(directory=assets_dir), name="assets")

# 挂载 /png 路由，解决图片 404 问题
png_dir = os.path.join(static_dir, 'png')
if os.path.isdir(png_dir):
    app.mount("/png", StaticFiles(directory=png_dir), name="png")


app.mount("/webui_dist", StaticFiles(directory=static_dir, html=True), name="static")




# 根路径 / 返回前端首页 index.html
from fastapi.responses import FileResponse
@app.get("/")
def serve_index():
    print("serve_index called")
    return FileResponse(os.path.join(static_dir, "index.html"))

# 新增 /HELP.md 路由，解决帮助文档加载失败问题
@app.get("/HELP.md")
def serve_help_md():
    help_md_path = os.path.join(static_dir, "HELP.md")
    if os.path.exists(help_md_path):
        return FileResponse(help_md_path, media_type="text/markdown")
    return JSONResponse({"success": False, "msg": "HELP.md not found"}, status_code=404)

@app.get("/api/config")
def api_get_config():
    try:
        # 直接返回配置字典，兼容前端
        return get_config()
    except Exception as e:
        return JSONResponse({"success": False, "msg": str(e)})

@app.post("/api/config")
async def api_save_config(config: dict):
    try:
        save_config(config)
        return {"success": True}
    except Exception as e:
        return {"success": False, "msg": str(e)}

@app.get("/api/bili/qrcode")
def api_get_qrcode():
    try:
        from tools.bili_api import get_qrcode
        img_path, url, qrcode_key = get_qrcode()
        # 前端需要qrcode_key用于后续轮询
        return FileResponse(img_path, headers={"X-QRCode-Url": url, "X-QRCode-Key": qrcode_key})
    except Exception as e:
        return JSONResponse({"success": False, "msg": str(e)})

from fastapi import Query
@app.get("/api/bili/qrcode_status")
def api_qrcode_status(qrcode_key: str, is_alt: bool = Query(False)):
    try:
        from tools.bili_api import poll_qrcode_status
        data = poll_qrcode_status(qrcode_key, is_alt=is_alt)
        return JSONResponse({"success": True, "data": data})
    except Exception as e:
        return JSONResponse({"success": False, "msg": str(e)})

@app.get("/api/bili/qrcode_status")
def api_qrcode_status():
    try:
        return JSONResponse({"success": True, "data": get_qrcode_status()})
    except Exception as e:
        return JSONResponse({"success": False, "msg": str(e)})


# 注册bili_check_cookie_api路由
from tools.bili_check_cookie_api import router as bili_check_cookie_router
app.include_router(bili_check_cookie_router)
import glob


# 日志接口，返回最新日志内容，并自动清理7天前的日志
@app.get("/api/logs")
def api_get_logs():
    import datetime
    log_dir = "data/logs"
    log_files = sorted(glob.glob(os.path.join(log_dir, "*.log")), reverse=True)
    if not log_files:
        return ""
    # 只返回最新日志的最后1000行
    with open(log_files[0], "r", encoding="utf-8") as f:
        lines = f.readlines()[-1000:]
    return "".join(lines)

from core.bilibili.manager import LiveRoomManager

# 全局直播间管理器实例（单例）
room_manager = None

def get_room_manager():
    global room_manager
    if room_manager is None:
        # 读取房间号
        config = get_global_config()
        room_id = config.get('bilibili', {}).get('room_id')
        room_manager = LiveRoomManager(room_id)
    return room_manager

from fastapi import Body

@app.post('/api/room/mute_user')
async def api_room_mute_user(data: dict = Body(...)):
    """
    请求体: { "uid": 123456, "minute": 5 }
    返回: { "success": true/false, "msg": "..." }
    """
    uid = data.get('uid')
    minute = data.get('minute', 5)
    if not uid:
        return {"success": False, "msg": "缺少uid"}
    try:
        manager = get_room_manager()
        ok = await manager.mute_user(int(uid), int(minute))
        return {"success": ok, "msg": "禁言成功" if ok else "禁言失败"}
    except Exception as e:
        return {"success": False, "msg": str(e)}


@app.post('/api/room/kick_user')
async def api_room_kick_user(data: dict = Body(...)):
    """
    请求体: { "uid": 123456 }
    返回: { "success": true/false, "msg": "..." }
    """
    uid = data.get('uid')
    if not uid:
        return {"success": False, "msg": "缺少uid"}
    try:
        manager = get_room_manager()
        ok = await manager.kick_user(int(uid))
        # 踢出成功后自动写入黑名单
        if ok:
            bl_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'config', 'blacklist_uid.txt')
            try:
                # 统一写入新格式，count=ban
                with open(bl_path, 'a', encoding='utf-8') as blf:
                    blf.write(f'{uid},ban\n')
            except Exception as e:
                print(f"[webui_server] 写入黑名单失败: {e}")
            # 主号或小号是房管时，自动调用B站官方接口拉黑
            try:
                block_ok = await manager.block_user(int(uid))
                if block_ok:
                    return {"success": True, "msg": "踢出并已B站官方拉黑"}
            except Exception as e:
                print(f"[webui_server] B站官方拉黑失败: {e}")
        return {"success": ok, "msg": "踢出成功" if ok else "踢出失败"}
    except Exception as e:
        return {"success": False, "msg": str(e)}


